| Conditions | 1 |
| Paths | 1 |
| Total Lines | 396 |
| Lines | 0 |
| Ratio | 0 % |
| Changes | 6 | ||
| Bugs | 0 | Features | 0 |
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
| 1 | /** global: Hammer */ |
||
| 26 | function ImagesCompare(element, options) { |
||
| 27 | element = $(element); |
||
| 28 | options = $.extend({}, defaults, options); |
||
| 29 | options.roundFactor = parseInt('1' + stringRepeat('0', options.precision)); |
||
| 30 | |||
| 31 | this._name = pluginName; |
||
| 32 | |||
| 33 | var frontElement, backElement, separator, dragHandle, lastRatio = 1, size = { |
||
| 34 | width: 0, |
||
| 35 | height: 0, |
||
| 36 | maxWidth: 0, |
||
| 37 | maxHeight: 0 |
||
| 38 | }, events = { |
||
| 39 | initialised: "imagesCompare:initialised", |
||
| 40 | changed: "imagesCompare:changed", |
||
| 41 | resized: "imagesCompare:resized" |
||
| 42 | }; |
||
| 43 | |||
| 44 | function onImagesLoaded() { |
||
| 45 | var images = element.find('img'), |
||
| 46 | totalImagesCount= images.length, |
||
| 47 | elementsLoaded = 0; |
||
| 48 | |||
| 49 | function onImageLoaded(){ |
||
| 50 | if (elementsLoaded >= totalImagesCount) { |
||
| 51 | init(); |
||
| 52 | } |
||
| 53 | } |
||
| 54 | |||
| 55 | images.each(function() { |
||
| 56 | // Image already loaded (cached) |
||
| 57 | if ($(this)[0].complete) { |
||
| 58 | totalImagesCount--; |
||
| 59 | onImageLoaded(); |
||
| 60 | } else { |
||
| 61 | // Image loading / error |
||
| 62 | $(this).on('load', function() { |
||
| 63 | elementsLoaded++; |
||
| 64 | onImageLoaded(); |
||
| 65 | }); |
||
| 66 | $(this).on('error', function() { |
||
| 67 | elementsLoaded++; |
||
| 68 | onImageLoaded(); |
||
| 69 | }); |
||
| 70 | } |
||
| 71 | }); |
||
| 72 | } |
||
| 73 | |||
| 74 | onImagesLoaded(); |
||
| 75 | |||
| 76 | function init() { |
||
| 77 | updateDom(); |
||
| 78 | patchSize(); |
||
| 79 | initInteractions(); |
||
| 80 | |||
| 81 | $(frontElement).attr('ratio', options.initVisibleRatio); |
||
| 82 | setVisibleRatio(options.initVisibleRatio); |
||
| 83 | |||
| 84 | // Let the world know we have done the init |
||
| 85 | element.trigger({ |
||
| 86 | type: events.initialised |
||
| 87 | }); |
||
| 88 | } |
||
| 89 | |||
| 90 | function addResize() { |
||
| 91 | $(window).on('resize', function (event) { |
||
| 92 | frontElement.css('clip', ''); |
||
| 93 | patchSize(); |
||
| 94 | setVisibleRatio(lastRatio); |
||
| 95 | |||
| 96 | // Let the world know we have done some resize updates |
||
| 97 | element.trigger({ |
||
| 98 | type: events.resized, |
||
| 99 | originalEvent: event |
||
| 100 | }); |
||
| 101 | }); |
||
| 102 | } |
||
| 103 | |||
| 104 | function initInteractions() { |
||
| 105 | options.interactionMode = options.interactionMode.toLowerCase(); |
||
| 106 | |||
| 107 | if (options.interactionMode != "drag" && options.interactionMode != "mousemove" && options.interactionMode != "click") { |
||
| 108 | console.warn('No valid interactionMode found, valid values are "drag", "mousemove", "click"'); |
||
| 109 | } |
||
| 110 | |||
| 111 | switch (options.interactionMode) { |
||
| 112 | case "drag": |
||
| 113 | initDrag(); |
||
| 114 | break; |
||
| 115 | case "mousemove": |
||
| 116 | initMouseMove(); |
||
| 117 | break; |
||
| 118 | case "click": |
||
| 119 | initClick(); |
||
| 120 | break; |
||
| 121 | default: |
||
| 122 | initDrag(); |
||
| 123 | } |
||
| 124 | } |
||
| 125 | |||
| 126 | function initDrag() { |
||
| 127 | if (typeof Hammer == 'undefined') { |
||
| 128 | console.error('Please include the hammerjs library for drag support'); |
||
| 129 | } |
||
| 130 | addDrag(); |
||
| 131 | addResize(); |
||
| 132 | } |
||
| 133 | |||
| 134 | function initMouseMove() { |
||
| 135 | addMouseMove(); |
||
| 136 | addResize(); |
||
| 137 | } |
||
| 138 | |||
| 139 | function initClick() { |
||
| 140 | addClick(); |
||
| 141 | addResize(); |
||
| 142 | } |
||
| 143 | |||
| 144 | function addClick() { |
||
| 145 | element.on('click', function (event) { |
||
| 146 | var ratio = getElementRatio(event.pageX); |
||
| 147 | setVisibleRatio(ratio); |
||
| 148 | }); |
||
| 149 | } |
||
| 150 | |||
| 151 | function addMouseMove() { |
||
| 152 | var lastMove = 0; |
||
| 153 | var eventThrottle = 1; |
||
| 154 | element.on('mousemove', function (event) { |
||
| 155 | event.preventDefault(); |
||
| 156 | var now = Date.now(); |
||
| 157 | if (now > lastMove + eventThrottle) { |
||
| 158 | lastMove = now; |
||
| 159 | var ratio = getElementRatio(event.pageX); |
||
| 160 | setVisibleRatio(ratio); |
||
| 161 | } |
||
| 162 | }); |
||
| 163 | |||
| 164 | element.on('mouseout', function (event) { |
||
| 165 | var ratio = getElementRatio(event.pageX); |
||
| 166 | setVisibleRatio(ratio); |
||
| 167 | }); |
||
| 168 | } |
||
| 169 | |||
| 170 | function addDrag() { |
||
| 171 | var hammertime = new Hammer(element[0]); |
||
| 172 | hammertime.get('pan').set({direction: Hammer.DIRECTION_HORIZONTAL}); |
||
| 173 | hammertime.on('pan', function (event) { |
||
| 174 | var ratio = getElementRatio(event.srcEvent.pageX); |
||
| 175 | setVisibleRatio(ratio); |
||
| 176 | }); |
||
| 177 | } |
||
| 178 | |||
| 179 | function updateDom() { |
||
| 180 | element.addClass('images-compare-container'); |
||
| 181 | element.css('display', 'inline-block'); |
||
| 182 | |||
| 183 | frontElement = element.find('> *:nth-child(1)'); |
||
| 184 | backElement = element.find('> *:nth-child(2)'); |
||
| 185 | |||
| 186 | frontElement.addClass("images-compare-before"); |
||
| 187 | frontElement.css('display', 'block'); |
||
| 188 | backElement.addClass("images-compare-after"); |
||
| 189 | backElement.css('display', 'block'); |
||
| 190 | |||
| 191 | if (options.addDragHandle) { |
||
| 192 | buildDragHandle(); |
||
| 193 | } |
||
| 194 | |||
| 195 | if (options.addSeparator) { |
||
| 196 | buildSeparator(); |
||
| 197 | } |
||
| 198 | } |
||
| 199 | |||
| 200 | function buildSeparator() { |
||
| 201 | element.prepend("<div class='images-compare-separator'></div>"); |
||
| 202 | separator = element.find(".images-compare-separator"); |
||
| 203 | |||
| 204 | } |
||
| 205 | |||
| 206 | function buildDragHandle() { |
||
| 207 | element.prepend("<div class='images-compare-handle'></div>"); |
||
| 208 | dragHandle = element.find(".images-compare-handle"); |
||
| 209 | dragHandle.append("<span class='images-compare-left-arrow'></span>"); |
||
| 210 | dragHandle.append("<span class='images-compare-right-arrow'></span>"); |
||
| 211 | } |
||
| 212 | |||
| 213 | function patchSize() { |
||
| 214 | var imgRef = backElement.find('img').first(); |
||
| 215 | setSize(imgRef.width(), imgRef.height(), imgRef.naturalWidth(), imgRef.naturalHeight()); |
||
| 216 | element.css('max-width', size.maxWidth + 'px'); |
||
| 217 | element.css('max-height', size.maxHeight + 'px'); |
||
| 218 | frontElement.width(size.width); |
||
| 219 | frontElement.height(size.height); |
||
| 220 | } |
||
| 221 | |||
| 222 | /** |
||
| 223 | * |
||
| 224 | * @param x |
||
| 225 | * @return float |
||
| 226 | */ |
||
| 227 | function getElementRatio(x) { |
||
| 228 | return roundRatio((x - element.offset().left) / frontElement.width()); |
||
| 229 | } |
||
| 230 | |||
| 231 | /** |
||
| 232 | * |
||
| 233 | * @param ratio |
||
| 234 | * @return float |
||
| 235 | */ |
||
| 236 | function roundRatio(ratio) { |
||
| 237 | ratio = Math.round((ratio * options.roundFactor)) / options.roundFactor; |
||
| 238 | if (ratio > 1) { |
||
| 239 | ratio = 1; |
||
| 240 | } |
||
| 241 | |||
| 242 | if (ratio < 0) { |
||
| 243 | ratio = 0; |
||
| 244 | } |
||
| 245 | |||
| 246 | return ratio; |
||
| 247 | |||
| 248 | } |
||
| 249 | |||
| 250 | /** |
||
| 251 | * Animation request |
||
| 252 | * |
||
| 253 | * @param startValue float |
||
| 254 | * @param endValue float |
||
| 255 | * @param duration value in ms |
||
| 256 | * @param easing linear or swing |
||
| 257 | */ |
||
| 258 | function launchAnimation(startValue, endValue, duration, easing) { |
||
|
|
|||
| 259 | $(frontElement).attr('ratio', startValue).animate({ratio: startValue}, { |
||
| 260 | duration: 0 |
||
| 261 | }); |
||
| 262 | |||
| 263 | $(frontElement).stop().attr('ratio', startValue).animate({ratio: endValue}, { |
||
| 264 | duration: duration, |
||
| 265 | easing: easing, |
||
| 266 | step: function (now) { |
||
| 267 | var width = getRatioValue(now); |
||
| 268 | lastRatio = now; |
||
| 269 | frontElement.attr('ratio', now).css('clip', 'rect(0, ' + width + 'px, ' + size.height + 'px, 0)'); |
||
| 270 | |||
| 271 | if (options.addSeparator) { |
||
| 272 | separator.css('left', width + 'px'); |
||
| 273 | } |
||
| 274 | |||
| 275 | if (options.addDragHandle) { |
||
| 276 | dragHandle.css('left', width + 'px'); |
||
| 277 | } |
||
| 278 | }, |
||
| 279 | done: function (animation, jumpedToEnd) { |
||
| 280 | var ratio = $(frontElement).attr('ratio'); |
||
| 281 | // Let the world know something has changed |
||
| 282 | element.trigger({ |
||
| 283 | type: events.changed, |
||
| 284 | ratio: ratio, |
||
| 285 | value: getRatioValue(ratio), |
||
| 286 | animate: true, |
||
| 287 | animation : animation, |
||
| 288 | jumpedToEnd: jumpedToEnd |
||
| 289 | }); |
||
| 290 | } |
||
| 291 | }); |
||
| 292 | } |
||
| 293 | |||
| 294 | /** |
||
| 295 | * Get value to reach, based on a ratio |
||
| 296 | * |
||
| 297 | * @param ratio float |
||
| 298 | * @return {number} |
||
| 299 | */ |
||
| 300 | function getRatioValue(ratio) { |
||
| 301 | ratio = Math.round((ratio * options.roundFactor)) / options.roundFactor; |
||
| 302 | return Math.round(frontElement.width() * ratio); |
||
| 303 | } |
||
| 304 | |||
| 305 | /** |
||
| 306 | * Change visible ratio |
||
| 307 | * |
||
| 308 | * @param ratio float |
||
| 309 | * @param animate boolean Do we want an animation ? |
||
| 310 | * @param duration in ms |
||
| 311 | * @param easing 'swing', 'linear' |
||
| 312 | */ |
||
| 313 | function setVisibleRatio(ratio, animate, duration, easing) { |
||
| 314 | if (typeof animate == 'undefined') { |
||
| 315 | animate = false; |
||
| 316 | } |
||
| 317 | |||
| 318 | var width = getRatioValue(ratio); |
||
| 319 | |||
| 320 | if (animate) { |
||
| 321 | var finalDuration = duration ? duration : options.animationDuration; |
||
| 322 | var finalEasing = easing ? easing : options.animationEasing; |
||
| 323 | |||
| 324 | launchAnimation(lastRatio, ratio, finalDuration, finalEasing); |
||
| 325 | |||
| 326 | // Let the world know something has changed |
||
| 327 | if (lastRatio != ratio) { |
||
| 328 | element.trigger({ |
||
| 329 | type: events.changed, |
||
| 330 | ratio: lastRatio, |
||
| 331 | value: width, |
||
| 332 | animate: animate |
||
| 333 | }); |
||
| 334 | } |
||
| 335 | |||
| 336 | return; |
||
| 337 | |||
| 338 | } else { |
||
| 339 | frontElement.stop().css('clip', 'rect(0, ' + width + 'px, ' + size.height + 'px, 0)'); |
||
| 340 | |||
| 341 | if (options.addSeparator) { |
||
| 342 | $(separator).stop().css('left', width + 'px'); |
||
| 343 | } |
||
| 344 | |||
| 345 | if (options.addDragHandle) { |
||
| 346 | dragHandle.css('left', width + 'px'); |
||
| 347 | } |
||
| 348 | } |
||
| 349 | |||
| 350 | // Let the world know something has changed |
||
| 351 | if (lastRatio != ratio) { |
||
| 352 | element.trigger({ |
||
| 353 | type: events.changed, |
||
| 354 | ratio: ratio, |
||
| 355 | value: width, |
||
| 356 | animate: animate |
||
| 357 | }); |
||
| 358 | } |
||
| 359 | |||
| 360 | lastRatio = ratio; |
||
| 361 | } |
||
| 362 | |||
| 363 | function setSize(width, height, maxWidth, maxHeight) { |
||
| 364 | if (typeof width != 'undefined') { |
||
| 365 | setWidth(width); |
||
| 366 | } |
||
| 367 | if (typeof height != 'undefined') { |
||
| 368 | setHeight(height); |
||
| 369 | } |
||
| 370 | if (typeof maxWidth != 'undefined') { |
||
| 371 | setMaxWidth(maxWidth); |
||
| 372 | } |
||
| 373 | if (typeof maxHeight != 'undefined') { |
||
| 374 | setMaxHeight(maxHeight); |
||
| 375 | } |
||
| 376 | return size; |
||
| 377 | } |
||
| 378 | |||
| 379 | function setWidth(width) { |
||
| 380 | size.width = width; |
||
| 381 | return size; |
||
| 382 | } |
||
| 383 | |||
| 384 | function setMaxWidth(maxWidth) { |
||
| 385 | size.maxWidth = maxWidth; |
||
| 386 | return size; |
||
| 387 | } |
||
| 388 | |||
| 389 | function setHeight(height) { |
||
| 390 | size.height = height; |
||
| 391 | return size; |
||
| 392 | } |
||
| 393 | |||
| 394 | function setMaxHeight(maxHeight) { |
||
| 395 | size.maxHeight = maxHeight; |
||
| 396 | return size; |
||
| 397 | } |
||
| 398 | |||
| 399 | // public function declaration |
||
| 400 | // returning element to preserve chaining |
||
| 401 | return { |
||
| 402 | "setValue": function (ratio, animate, duration, easing) { |
||
| 403 | setVisibleRatio(ratio, animate, duration, easing); |
||
| 404 | return element; |
||
| 405 | }, |
||
| 406 | "getValue": function () { |
||
| 407 | return lastRatio; |
||
| 408 | }, |
||
| 409 | "on": function (eventName, callback) { |
||
| 410 | element.on(eventName, callback); |
||
| 411 | return element; |
||
| 412 | }, |
||
| 413 | "off": function (eventName, callback) { |
||
| 414 | element.off(eventName, callback); |
||
| 415 | return element; |
||
| 416 | }, |
||
| 417 | "events": function () { |
||
| 418 | return events; |
||
| 419 | } |
||
| 420 | }; |
||
| 421 | } |
||
| 422 | |||
| 472 |